package com.icare.common.service.log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Stopwatch;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 日志打印切面
 *
 * @author TianHaibo
 * @create 2017-12-08 17:38
 **/
@Aspect
@Component
public class LogAspect {

    private static final Logger log = LoggerFactory.getLogger(LogAspect.class);

    /**
     * 定义切入点
     */
    @Pointcut("execution(* com.icare..*Impl.*(..))")
    public void doLogService(){}

    @Pointcut("execution(* com.icare..*Socket.*(..))")
    public void doLogSocket(){}

    @Pointcut("execution(* com.icare..*Rest.*(..))")
    public void doLogRest(){}

    @Around("doLogRest() || doLogService() || doLogSocket()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{
        Signature signature = joinPoint.getSignature();
        String methodName = signature.getName();
        String className = signature.getDeclaringTypeName();
        List<Object> objects = Arrays.asList(joinPoint.getArgs());
        Stopwatch started = Stopwatch.createStarted();
        Object proceed = null;
        try {
            if (objects != null) {
                if (objects.size() > 1) {
                    log.info("{\"开始执行class\":\"{}\",\"开始执行method\":\"{}\"}",className,methodName);
                    final AtomicInteger index = new AtomicInteger(1);
                    objects.stream().filter(x -> x instanceof Serializable).forEach(x -> {
                        if(x instanceof MultipartFile) {
                            log.info("{\"入参{}\":\"{}\"}", index.get(), null==x ? "空文件" : ((MultipartFile)x).getName());
                        } else {
                            log.info("{\"入参{}\":{}}", index.get(), JSONObject.toJSONString(x));
                        }
                        index.incrementAndGet();
                    });
                } else {
                    if (objects.size()>0 && objects.get(0) instanceof Serializable) {
                        log.info("{\"开始执行class\":\"{}\",\"开始执行method\":\"{}\",\"入参\":{}}", className,methodName,JSONObject.toJSONString(objects.get(0)));
                    }
                }
            }
            proceed = joinPoint.proceed();
        } finally {
            started.stop();
            if(proceed!=null) {
                log.info("{\"完成执行class\":\"{}\",\"完成执行method\":\"{}\",\"返回结果\":\"{}\",\"耗时\":{}}",className,methodName,JSON.toJSONString(proceed),started.elapsed(TimeUnit.MILLISECONDS));
            }
        }
        return proceed;
    }
}
